home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / utils / file / managers / mc-3.2 / mc-3 / mc-3.2.1 / tk / tkmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-17  |  8.6 KB  |  409 lines

  1. /* Midnight Commander Tk initialization and main loop
  2.    Copyright (C) 1995 Miguel de Icaza
  3.    Copyright (C) 1995 Jakub Jelinek
  4.    
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 2 of the License, or
  8.    (at your option) any later version.
  9.    
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. /*
  20.  * The Tk version of the code tries to use as much code as possible
  21.  * from the curses version of the code, so we Tk as barely as possible
  22.  * and manage most of the events ourselves.  This may cause some
  23.  * confusion at the beginning.
  24.  */
  25.  
  26. #include <config.h>
  27. #include <stdarg.h>
  28. #include <string.h>
  29. #include <ctype.h>
  30. #include "tkmain.h"
  31. #include "key.h"
  32. #include "global.h"
  33. #include "tty.h"        /* for KEY_BACKSPACE */
  34.  
  35. /* Tcl interpreter */
  36. Tcl_Interp *interp;
  37.  
  38. /* if true, it's like mc, otherwise is like mxc */
  39. int use_one_window = 1;
  40.  
  41. static char *display = NULL;
  42.  
  43. /* Used to quote the next character, emulates mi_getch () */
  44. static int mi_getch_waiting = 0;
  45. static int mi_getch_value;
  46.  
  47. static Tk_ArgvInfo arg_table[] = {
  48. {"-display", TK_ARGV_STRING, (char *) NULL, (char *) &display,
  49.              "Display to use"},
  50. {(char *) NULL, TK_ARGV_END, (char *) NULL, (char *) NULL,
  51.              (char *) NULL}
  52. };
  53.  
  54. static int tkmc_callback (ClientData cd, Tcl_Interp *i, int ac, char *av[]);
  55.  
  56. int
  57. xtoolkit_init (int *argc, char *argv[])
  58. {
  59.     interp = Tcl_CreateInterp ();
  60.     if (Tk_ParseArgv (interp, (Tk_Window) NULL, argc, argv, arg_table, 0)
  61.     != TCL_OK) {
  62.     fprintf(stderr, "%s\n", interp->result);
  63.     exit(1);
  64.     }
  65.  
  66.     /* Pass DISPLAY variable to child procedures */
  67.     if (display != NULL) {
  68.     Tcl_SetVar2 (interp, "env", "DISPLAY", display, TCL_GLOBAL_ONLY);
  69.     }
  70.  
  71.     Tcl_SetVar(interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
  72.     
  73.     Tcl_SetVar(interp, "one_window",
  74.            use_one_window ? "1" : "0", TCL_GLOBAL_ONLY);
  75.  
  76.     /*
  77.      * Initialize the Tk application.
  78.      */
  79. #ifdef OLD_VERSION
  80.     tkwin = Tk_CreateMainWindow (interp, display, "Midnight Commander","tkmc");
  81. #endif
  82.     if (Tcl_Init (interp) != TCL_OK){
  83.     fprintf (stderr, "%s\n", interp->result);
  84.     exit (1);
  85.     }
  86.     if (Tk_Init (interp) != TCL_OK){
  87.     fprintf (stderr, "%s\n", interp->result);
  88.     exit (1);
  89.     }
  90.     
  91.     Tcl_CreateCommand (interp, "tkmc", tkmc_callback, 0, 0);
  92.     if (Tcl_EvalFile (interp, LIBDIR "mc.tcl") == TCL_OK)
  93.     return 0;
  94.     else {
  95.     printf ("%s\n", interp->result);
  96.     exit (1);
  97.     }
  98. }
  99.  
  100. int
  101. xtoolkit_end (void)
  102. {
  103.     /* Cleanup */
  104.     Tcl_Eval (interp, "exit");
  105.     return 1;
  106. }
  107.  
  108. void
  109. tk_evalf (char *format, ...)
  110. {
  111.     va_list ap;
  112.     char buffer [1024];
  113.  
  114.     va_start (ap, format);
  115.     vsprintf (buffer, format, ap);
  116.     if (Tcl_Eval (interp, buffer) != TCL_OK){
  117.     fprintf (stderr, "[%s]: %s\n", buffer, interp->result);
  118.     }
  119.     va_end (ap);
  120. }
  121.  
  122. int
  123. tk_evalf_val (char *format, ...)
  124. {
  125.     va_list ap;
  126.     char buffer [1024];
  127.     int r;
  128.  
  129.     va_start (ap, format);
  130.     vsprintf (buffer, format, ap);
  131.     r = Tcl_Eval (interp, buffer);
  132.     va_end (ap);
  133.     return r;
  134. }
  135.  
  136. widget_data
  137. xtoolkit_create_dialog (Dlg_head *h)
  138. {
  139.     char *dialog_name = copy_strings (".", h->name, 0);
  140.     
  141.     tk_evalf ("toplevel %s", dialog_name);
  142.     return (widget_data) dialog_name;
  143. }
  144.  
  145. void
  146. x_set_dialog_title (Dlg_head *h, char *title)
  147. {
  148.     tk_evalf ("wm title %s {%s}", (char *)(h->wdata), title);
  149. }
  150.  
  151. widget_data
  152. xtoolkit_get_main_dialog (Dlg_head *h)
  153. {
  154.     return (widget_data) strdup (".");
  155. }
  156.  
  157. /* Creates the containers */
  158. widget_data
  159. x_create_panel_container (int which)
  160. {
  161.     char *s, *cmd;
  162.  
  163.     cmd  = use_one_window ? "frame" : "toplevel";
  164.     s   = which ? ".right" : ".left";
  165.     tk_evalf ("%s %s", cmd, s);
  166.  
  167.     return (widget_data) s;
  168. }
  169.  
  170. void
  171. x_panel_container_show (widget_data wdata)
  172. {
  173. }
  174.  
  175. int
  176. do_esc_key (int d)
  177. {
  178.     if (isdigit(d))
  179.     return KEY_F(d-'0');
  180.     if ((d >= 'a' && d <= 'z') || (d >= 'A' && d <= 'Z' )
  181.     || d == '\n' || d == '\t' || d == XCTRL ('h') || d == '!'
  182.     || d == KEY_BACKSPACE || d == 127 || d == '\r')
  183.     return ALT(d);
  184.     else {
  185.     return ESC_CHAR;
  186.     }
  187. }
  188.  
  189. /* This commands has this sintax:
  190.  * [r|a|c] ascii
  191.  *
  192.  * r, a, c, k: regular, alt, control, keysym
  193.  */
  194.  
  195. static int
  196. tkmc_callback (ClientData cd, Tcl_Interp *i, int ac, char *av[])
  197. {
  198.     Dlg_head *h = current_dlg;
  199.     int key;
  200.     static int got_esc;
  201.  
  202.     key = av [2][0];
  203.  
  204.     if (av [1][0] == 'c' || av [1][0] == 'a'){
  205.     if (!key)
  206.         return TCL_OK;
  207.     
  208.     /* Regular? */
  209.     
  210.     if (!isascii (key)){
  211.         return TCL_OK;
  212.     } else { 
  213.         key = tolower (key);
  214.     }
  215.     }
  216.     
  217.     switch (av [1][0]){
  218.     case 'a':
  219.     key = ALT(key);
  220.     break;
  221.  
  222.     case 'c':
  223.     key = XCTRL(key);
  224.     break;
  225.  
  226.     case 'r':
  227.     if (!key)
  228.         return TCL_OK;
  229.     break;
  230.     
  231.     case 'k':
  232.     if (!(key = lookup_keysym (av [2])))
  233.         return TCL_OK;
  234.     break;
  235.     }
  236.     
  237.     if (key == '\r')
  238.     key = '\n';
  239.  
  240.     if (key == ESC_CHAR){
  241.     if (!got_esc){
  242.         got_esc = 1;
  243.         return TCL_OK;
  244.     }
  245.     got_esc = 0;
  246.     }
  247.  
  248.     if (got_esc){
  249.     key = do_esc_key (key);
  250.     got_esc = 0;
  251.     }
  252.  
  253.     if (mi_getch_waiting && key){
  254.     mi_getch_waiting = 0;
  255.     mi_getch_value = key;
  256.     return TCL_OK;
  257.     }
  258.     dlg_key_event (h, key);
  259.     update_cursor (h);
  260.     return TCL_OK;
  261. }
  262.  
  263. void
  264. tk_focus_widget (Widget_Item *p)
  265. {
  266.     char *wname;
  267.  
  268.     if (!p->widget)
  269.     return;
  270.     
  271.     wname = (char *) p->widget->wdata;
  272.  
  273.     if (!wname)
  274.     return;
  275.  
  276.     tk_evalf ("focus %s", wname+1);
  277. }
  278.  
  279. /* This routine uses the grid geometry manager to layout
  280.  * the widgets inside the dialog.  This is called if no
  281.  * layout routine has been defined for the window
  282.  * it also calls a post layout routine to spice up the dialog
  283.  */
  284. void
  285. do_grid_layout (Dlg_head *h, char *wname)
  286. {
  287.     const int cols  = h->cols;
  288.     const int lines = h->lines;
  289.     const int widgets = h->count;
  290.     const int wherex = h->x;
  291.     const int wherey = h->y;
  292.     Widget_Item *h_track;
  293.     int i, height, width;
  294.  
  295. #if 0
  296.     for (i = 0; i < cols; i++){
  297.     int j;
  298.  
  299.     for (j = 0; j < lines; j++){
  300.         tk_evalf ("frame %s.f%d-%d -height 18 -width 10", wname, i, j);
  301.         tk_evalf ("grid configure %s.f%d-%d -row %d -column %d", wname, i, j, j, i);
  302.     }
  303.     }
  304. #endif
  305.     tk_evalf_val ("set $setup(heightc)");
  306.     height = atoi (interp->result) * 2;
  307.     tk_evalf_val ("set $setup(widthc)");
  308.     width = atoi (interp->result) *2;
  309.  
  310.     if (height == 0 || width == 0){
  311.     fprintf (stderr, "valiste verga\n");
  312.     height = 30;
  313.     width = 20;
  314.     }
  315.     h_track = h->current;
  316.     for (i = 0; i < widgets; i++){
  317.     fprintf (stderr, "%s goes to: %d %d\n\r", (char *) h_track->widget->wdata,
  318.           h_track->widget->x - wherex, h_track->widget->y-wherey);
  319.     tk_evalf ("place configure %s -x %d -y %d ",
  320.           ((char *) (h_track->widget->wdata))+1, 
  321.           (h_track->widget->x - wherex) * width,
  322.           (h_track->widget->y - wherey) * height);
  323.     h_track = h_track->prev;
  324.     }
  325. }
  326.  
  327. /* Setup done before using tkrundlg_event */
  328. void
  329. tk_init_dlg (Dlg_head *h)
  330. {
  331.     Widget_Item *h_track;
  332.     char *wname;
  333.     int i;
  334.  
  335.     /* Set wlist to hold all the widget names that will be ran */
  336.     tk_evalf ("set wlist {}");
  337.     h_track = h->current;
  338.     for (i = 0; i < h->count; i++){
  339.     char *wname = (char *)h_track->widget->wdata;
  340.     if (wname)
  341.         tk_evalf ("set wlist \"%s $wlist\"", wname+1);
  342.     h_track = h_track->prev;
  343.     }
  344.  
  345.     wname = (char *) h->wdata;
  346.     
  347.     /* Layout the window, if no layout routine is defined, use grided layout */
  348.     if (tk_evalf_val ("layout_%s", h->name) != TCL_OK)
  349.     do_grid_layout (h, wname);
  350.  
  351.     /* setup window bindings */
  352.     tk_evalf ("bind_setup %s", wname);
  353.  
  354.     /* If this is not the main window, center it */
  355.     if (wname [0] && wname [1]){
  356.     tk_evalf ("center_win %s", wname);
  357.     }
  358. }
  359.  
  360. int
  361. tkrundlg_event (Dlg_head *h)
  362. {
  363.     /* Run the dialog */
  364.     while (h->running){
  365.     if (h->send_idle_msg){
  366.         if (Tcl_DoOneEvent (TCL_DONT_WAIT))
  367.         if (idle_hook)
  368.             execute_hooks (idle_hook);
  369.         
  370.         while (Tcl_DoOneEvent (TCL_DONT_WAIT) &&
  371.            h->running && h->send_idle_msg){
  372.         (*h->callback) (h, 0, DLG_IDLE);
  373.         }
  374.     } else 
  375.         Tcl_DoOneEvent (TCL_ALL_EVENTS); 
  376.     }
  377.  
  378.     return 1;
  379. }
  380.  
  381. int
  382. Tcl_AppInit (Tcl_Interp *interp)
  383. {
  384.     return TCL_OK;
  385. }
  386.  
  387. void
  388. x_interactive_display ()
  389. {
  390. }
  391.  
  392. int
  393. tk_getch ()
  394. {
  395.     mi_getch_waiting = 1;
  396.     
  397.     while (mi_getch_waiting)
  398.     Tk_DoOneEvent (TK_ALL_EVENTS);
  399.     
  400.     return mi_getch_value;
  401. }
  402.  
  403. void
  404. tk_dispatch_all (void)
  405. {
  406.     while (Tk_DoOneEvent (TK_DONT_WAIT))
  407.     ;
  408. }
  409.